package com.atguigu.gulimall.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.cart.Interceptor.CatInterceptor;
import com.atguigu.gulimall.cart.feign.ProductFeign;
import com.atguigu.gulimall.cart.service.CartService;
import com.atguigu.gulimall.cart.vo.CartItemVo;
import com.atguigu.gulimall.cart.vo.CartVo;
import com.atguigu.gulimall.cart.vo.SkuInfoVo;
import com.atguigu.gulimall.cart.vo.UserInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService{

    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    ProductFeign productFeign;
    @Autowired
    ThreadPoolExecutor executor;
    public static final String CART="cart:";

    /**
     * 添加购物车
     */
    @Override
    public CartItemVo addToCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {

        String cartId;
        //判断购物车是否是临时购物车
        UserInfoVo userInfoVo = CatInterceptor.threadlocal.get();
       // userInfoVo.setId(3L);
        if (userInfoVo.getId()!=null){
            //不是临时购物车
            cartId=CART+userInfoVo.getId();
        }else {
            cartId = CART+userInfoVo.getUserKey();
        }
        //绑定reids
       BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(cartId);
        //从reids总获取该商品的信息
        String o = (String) operations.get(skuId.toString());
        //判断此商品购物车中是否存在
        if (StringUtils.isEmpty(o)){
            CartItemVo itemVo = new CartItemVo();
            CompletableFuture<Void> getSkuInfo = CompletableFuture.runAsync(() -> {
                //根据id查询商品信息
                R info = productFeign.info(skuId);
                SkuInfoVo skuInfo = info.getData(new TypeReference<SkuInfoVo>() {
                });
                //封装购物车商品信息
                itemVo.setCount(num);
                itemVo.setImg(skuInfo.getSkuDefaultImg());
                itemVo.setPrice(skuInfo.getPrice());
                itemVo.setTitle(skuInfo.getSkuTitle());
                itemVo.setSkuId(skuInfo.getSkuId());
            },executor);

            CompletableFuture<Void> getAttr = CompletableFuture.runAsync(() -> {
                //查询商品参数信息 远程调用接口
                List<String> attrNameValue = productFeign.getAttrNameValue(skuId);
                itemVo.setSkuAttr(attrNameValue);
            },executor);

            //阻塞等待线程
            CompletableFuture.allOf(getSkuInfo,getAttr).get();
            String s = JSON.toJSONString(itemVo);
            //把购物车信息放入reids中
            operations.put(skuId.toString(),s);
            return itemVo;
        }else {
            //购物车中有此商品
            CartItemVo itemVo = JSON.parseObject(o, CartItemVo.class);
            itemVo.setCount(itemVo.getCount()+num);
            //再次修改redis中的值
            operations.put(skuId.toString(),JSON.toJSONString(itemVo));
            return itemVo;
        }
    }

    /**
     * 购物车列表
     * @return
     */
    @Override
    public CartVo getCartList() throws ExecutionException, InterruptedException {
        UserInfoVo userInfoVo = CatInterceptor.threadlocal.get();
        //userInfoVo.setId(3L);
        CartVo vo = new CartVo();
        String id = "";
        //判断用户是否登陆
        if (userInfoVo.getId()!=null){
            //登陆
            //1.获取临时购物车
            id = CART+userInfoVo.getUserKey();
            List<CartItemVo> cart = getCart(id);
            //2.判断临时购物车是否为空
            if (cart!=null){
                //合并购物车
                //redisTemplate.multi();
                for (CartItemVo itemVo : cart) {
                    CartItemVo cartItemVo = addToCart(itemVo.getSkuId(), itemVo.getCount());
                }
                System.out.println("shan");
                //int i = 10/0;
                //清空临时购物车
                clearCart(id);
                //redisTemplate.exec();
            }
            //3.获取用户登陆的购物车信息
            String userId =CART+userInfoVo.getId().toString();
            List<CartItemVo> cartItemVos = getCart(userId);
            vo.setVos(cartItemVos);
            return vo;
        }else {
            //没登陆
            //1.1获取临时购物车id
            id = CART+userInfoVo.getUserKey();
            List<CartItemVo> cart = getCart(id);
            vo.setVos(cart);
            Integer countNum = vo.getCountNum();
            BigDecimal coutPrice = vo.getCoutPrice();
            return vo;
        }
    }

    @Override
    public void clearCart(String id) {
        Boolean delete = redisTemplate.delete(id);
    }

    /**
     * 删除购物项
     * @param skuId
     */
    @Override
    public void deleteItem(Long skuId) {
        //获取购物车
        BoundHashOperations<String, Object, Object> cart = getCart();
        //删除购物项
        cart.delete(skuId.toString());
    }

    /**
     * 远程调用获取购物项
     * @return
     */
    @Override
    public List<CartItemVo> getCartOrder() {
        UserInfoVo userInfoVo = CatInterceptor.threadlocal.get();
        //userInfoVo.setId(3L);
        if (userInfoVo.getId()!=null){
            String id = CART+userInfoVo.getId();
            List<CartItemVo> cart = this.getCart(id);
            List<CartItemVo> collect = cart.stream().filter(item -> item.getCheck()).map(item->{
                //获取购物项最新的价格 根据商品id查询价格
                BigDecimal price = productFeign.getPrice(item.getSkuId());
                item.setPrice(price);
                return item;
            }).collect(Collectors.toList());
            return collect;
        }
        return null;
    }

    @Override
    public void UpdateCartItem(Integer skuId, Integer check) {
        //获取该商品购物项信息
        CartItemVo cartItem = getCartItem(skuId);
        cartItem.setCheck(check==1?true:false);
        String string = JSON.toJSONString(cartItem);
        BoundHashOperations<String, Object, Object> operations = getCartName();
        operations.put(skuId.toString(),string);
    }

    /**
     * 获取购物车信息
     * @param skuId
     * @return
     */
    @Override
    public CartItemVo getCartNum(Long skuId) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        Object o =  cart.get(skuId.toString());
        CartItemVo itemVo = JSON.parseObject(o.toString(), CartItemVo.class);
        return itemVo;
    }

    /**
     * 获取购物车
     */
    public BoundHashOperations<String, Object, Object>  getCart(){
        String cartId;
        //判断购物车是否是临时购物车
        UserInfoVo userInfoVo = CatInterceptor.threadlocal.get();
        if (userInfoVo.getId()!=null){
            //不是临时购物车
            cartId=CART+userInfoVo.getId();
        }else {
            cartId = CART+userInfoVo.getUserKey();
        }
        //绑定reids
        BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(cartId);
        return operations;
    }

    /**
     * 从redis获取购物车信息
     * @param id
     * @return
     */
    private List<CartItemVo> getCart(String id) {
        //从redis中查询购物车中的数据
        List<Object> values = redisTemplate.boundHashOps(id).values();
        //遍历购物车   16251d58-15c4-4620-beff-b0d5dcfc0b03cart:
        List<CartItemVo> itemVos = values.stream().map(obj -> {
            String string = (String) obj;
            //封装购物车数据
            CartItemVo itemVo = JSON.parseObject(string, CartItemVo.class);
            return itemVo;
        }).collect(Collectors.toList());
        return itemVos;
    }

    /**
     * 获取购物项
     */
    public CartItemVo getCartItem(Integer skuId){
        String cartId;
        //判断购物车是否是临时购物车
        UserInfoVo userInfoVo = CatInterceptor.threadlocal.get();
        // userInfoVo.setId(3L);
        if (userInfoVo.getId()!=null){
            //不是临时购物车
            cartId=CART+userInfoVo.getId();
        }else {
            cartId = CART+userInfoVo.getUserKey();
        }
        BoundHashOperations<String, Object, Object> hashOps = redisTemplate.boundHashOps(cartId);
        //根据商品id获取购物项信息
        Object vo =  hashOps.get(skuId.toString());
        CartItemVo itemVo = JSON.parseObject(vo.toString(), CartItemVo.class);
        return itemVo;
    }

    /**
     * 获取购物车
     */
    public BoundHashOperations<String, Object, Object> getCartName(){
        String cartId;
        //判断购物车是否是临时购物车
        UserInfoVo userInfoVo = CatInterceptor.threadlocal.get();
        // userInfoVo.setId(3L);
        if (userInfoVo.getId()!=null){
         //不是临时购物车
            cartId=CART+userInfoVo.getId();
        }else {
            cartId = CART+userInfoVo.getUserKey();
        }
        BoundHashOperations<String, Object, Object> hashOps = redisTemplate.boundHashOps(cartId);
        return hashOps;
    }

}
